package br.senai.sc.controller.business;

import java.io.Serializable;
import java.math.BigInteger;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jboss.seam.international.status.Messages;
import org.jboss.seam.international.status.builder.BundleKey;

import br.senai.sc.model.CondicaoClimatica;
import br.senai.sc.util.SystemConstants;

/**
 * Contém regras de negócio relacionadas a {@link CondicaoClimatica}
 * 
 * @author Tiago Wanke Marques &lt;tiago.marques@sc.senai.br&gt;
 */
public class CondicaoClimaticaBusiness implements Serializable {

	private static final long serialVersionUID = 1L;

	@PersistenceContext
	private EntityManager em;

	@Inject
	private Messages messages;

	/**
	 * Verifica se existe uma {@link CondicaoClimatica} com o mesmo
	 * {@link CondicaoClimatica#getNome()} cadastrado. Se informado null retorna
	 * false.
	 * 
	 * @param condicao
	 * @return True caso exista uma {@link CondicaoClimatica} cadastrada com
	 *         nome igual, false caso contrário.
	 */
	public boolean condicaoClimaticaComMesmoNome(CondicaoClimatica condicao) {

		if ((condicao == null) || (condicao.getNome() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM condicao_climatica cc WHERE nome LIKE :nome")
				.setParameter("nome", condicao.getNome()).getSingleResult();

		return total.intValue() > 0;
	}

	/**
	 * Se informado null retorna false.
	 * 
	 * @param condicao
	 * @return True caso a {@link CondicaoClimatica} exista, false caso
	 *         contrário.
	 */
	public boolean condicaoClimaticaExiste(CondicaoClimatica condicao) {

		if ((condicao == null) || (condicao.getIdCondicaoClimatica() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM condicao_climatica cc WHERE id_condicao_climatica = :idCondicaoClimatica")
				.setParameter("idCondicaoClimatica",
						condicao.getIdCondicaoClimatica()).getSingleResult();
		return total.intValue() > 0;
	}

	/**
	 * @param condicao
	 *            Caso informado null retorna false.
	 * @return True caso exista uma {@link CondicaoClimatica} com mesmo nome,
	 *         porém com id diferente, false caso contrário.
	 */
	public boolean condicaoClimaticaComMesmoNomeIdDiferente(
			CondicaoClimatica condicao) {

		if ((condicao == null) || (condicao.getNome() == null)
				|| (condicao.getIdCondicaoClimatica() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM condicao_climatica cc WHERE nome LIKE :nome AND id_condicao_climatica != :idCondicaoClimatica")
				.setParameter("nome", condicao.getNome())
				.setParameter("idCondicaoClimatica",
						condicao.getIdCondicaoClimatica()).getSingleResult();

		return total.intValue() > 0;
	}

	/**
	 * @param condicao
	 *            Caso informado null retorna false.
	 * @return True caso a {@link CondicaoClimatica} possui referência para
	 *         {@link br.senai.sc.model.Amostra}, false caso contrário.
	 */
	public boolean contemAmostra(CondicaoClimatica condicao) {

		if ((condicao == null) || (condicao.getIdCondicaoClimatica() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM amostra a WHERE id_condicao_climatica = :idCondicaoClimatica")
				.setParameter("idCondicaoClimatica",
						condicao.getIdCondicaoClimatica()).getSingleResult();

		return total.intValue() > 0;
	}

	/**
	 * @return True caso existe {@link CondicaoClimatica} cadastrada no sistema,
	 *         false caso contrário.
	 */
	public boolean existeCondicaoClimaticaCadastrada() {

		BigInteger total = (BigInteger) em.createNativeQuery(
				"SELECT count(*) FROM condicao_climatica cc").getSingleResult();

		return total.intValue() > 0;
	}

	/**
	 * Executa os métodos necessários para verificar se a
	 * {@link CondicaoClimatica} pode ser salva. Caso houver alguma
	 * inconsistência adiciona ao atributo de mensagens da classe.
	 * 
	 * @param condicao
	 * @return True caso a {@link CondicaoClimatica} pode ser salva, false caso
	 *         contrário.
	 */
	public boolean podeSalvarCondicaoClimatica(CondicaoClimatica condicao) {

		messages.clear();
		if (condicaoClimaticaComMesmoNome(condicao)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"condicoesClimaticas.validacao.condicaoClimaticaComMesmoNome"));
		}

		return messages.isEmpty();
	}

	/**
	 * Executa os métodos necessários para verificar se a
	 * {@link CondicaoClimatica} pode ser editada. Caso houver alguma
	 * inconsistência adiciona ao atributo de mensagens da classe.
	 * 
	 * @param condicao
	 * @return True caso a {@link CondicaoClimatica} pode ser editada, false
	 *         caso contrário.
	 */
	public boolean podeEditarCondicaoClimatica(CondicaoClimatica condicao) {

		messages.clear();

		if (!condicaoClimaticaExiste(condicao)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"condicoesClimaticas.validacao.condicaoClimaticaInexistente"));
		}

		if (condicaoClimaticaComMesmoNomeIdDiferente(condicao)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"condicoesClimaticas.validacao.condicaoClimaticaComMesmoNome"));
		}

		return messages.isEmpty();
	}

	/**
	 * Executa os métodos necessários para verificar se a
	 * {@link CondicaoClimatica} pode ser removida. Caso houver alguma
	 * inconsistência adiciona ao atributo de mensagens da classe.
	 * 
	 * @param condicao
	 * @return True caso a {@link CondicaoClimatica} pode ser removida, false
	 *         caso contrário.
	 */
	public boolean podeRemoverCondicaoClimatica(CondicaoClimatica condicao) {

		messages.clear();

		if (!condicaoClimaticaExiste(condicao)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"condicoesClimaticas.validacao.condicaoClimaticaInexistente"));
		}

		if (contemAmostra(condicao)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"condicoesClimaticas.validacao.contemAmostra"));
		}

		return messages.isEmpty();
	}

}
